using AutoMapper;
using UwinEducation.Application.Common.Interfaces;
using UwinEducation.Application.Dtos;
using UwinEducation.Domain.Entities;
using UwinEducation.Domain.IRepositories;
using UwinEducation.Shared;
using UwinEducation.Shared.Models;

namespace UwinEducation.Application.Services
{
    /// <summary>
    /// 用户服务实现
    /// </summary>
    public class UserService : IUserService
    {
        private readonly IUserRepository _userRepository;
        private readonly IUserRoleRepository _userRoleRepository;
        private readonly IPasswordHasher _passwordHasher;
        private readonly ICacheService _cacheService;
        private readonly IMapper _mapper;

        public UserService(
            IUserRepository userRepository,
            IUserRoleRepository userRoleRepository,
            IPasswordHasher passwordHasher,
            ICacheService cacheService,
            IMapper mapper)
        {
            _userRepository = userRepository;
            _userRoleRepository = userRoleRepository;
            _passwordHasher = passwordHasher;
            _cacheService = cacheService;
            _mapper = mapper;
        }

        /// <summary>
        /// 获取用户分页列表
        /// </summary>
        public async Task<PagedResult<UserDto>> GetPagedListAsync(UserPageRequest pageRequest)
        {
            var result = await _userRepository.GetPagedListAsync(pageRequest);
            var userDtos = new List<UserDto>();

            foreach (var user in result.Items)
            {
                var userDto = _mapper.Map<UserDto>(user);
                var roleInfos = await _userRoleRepository.GetRoleInfosByUserIdAsync(user.Id);
                userDto.Roles = roleInfos.Select(r => new RoleInfo { Id = r.Id, Name = r.Name }).ToList();
                userDtos.Add(userDto);
            }

            return new PagedResult<UserDto>
            {
                Total = result.Total,
                Items = userDtos
            };
        }

        /// <summary>
        /// 获取用户详情
        /// </summary>
        public async Task<UserDto> GetByIdAsync(Guid id)
        {
            var user = await _userRepository.GetDetailsByIdAsync(id);
            if (user == null)
            {
                throw new ArgumentException($"用户不存在: {id}");
            }

            var userDto = _mapper.Map<UserDto>(user);
            var roleInfos = await _userRoleRepository.GetRoleInfosByUserIdAsync(id);
            userDto.Roles = roleInfos.Select(r => new RoleInfo { Id = r.Id, Name = r.Name }).ToList();
            
            return userDto;
        }

        /// <summary>
        /// 创建用户
        /// </summary>
        public async Task<UserDto> CreateAsync(CreateUserDto input)
        {
            // 检查用户名是否已存在
            if (await _userRepository.ExistsByUserNameAsync(input.UserName))
            {
                throw new ArgumentException($"用户名已存在: {input.UserName}");
            }

            // 创建用户实体
            var user = User.Create(
                input.UserName,
                input.RealName??string.Empty,
                input.PhoneNumber ?? string.Empty,
                input.Email ?? string.Empty,
                _passwordHasher.HashPassword(input.Password)
            );
            // 保存用户
            await _userRepository.AddAsync(user);

            // 分配角色
            if (input.RoleIds?.Any() == true)
            {
                var userRoles = input.RoleIds.Select(roleId => UserRole.Create(user.Id, roleId));
                await _userRoleRepository.AddRangeAsync(userRoles);
            }

            return await GetByIdAsync(user.Id);
        }

        /// <summary>
        /// 更新用户
        /// </summary>
        public async Task<UserDto> UpdateAsync(UpdateUserDto input)
        {
            var user = await _userRepository.GetByIdAsync(input.Id);
            if (user == null)
            {
                throw new ArgumentException($"用户不存在: {input.Id}");
            }

            // 更新用户信息
            user.Update(
                input.UserName,
                input.RealName ?? user.RealName,
                input.PhoneNumber ?? user.PhoneNumber,
                input.Email ?? user.Email,
                input.IsEnabled
            );

            await _userRepository.UpdateAsync(user);

            // 清除用户权限缓存
            await _cacheService.RemoveAsync($"user_permissions:{user.Id}");

            return await GetByIdAsync(user.Id);
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        public async Task DeleteAsync(Guid id)
        {
            var user = await _userRepository.GetByIdAsync(id);
            if (user == null)
            {
                throw new ArgumentException($"用户不存在: {id}");
            }

            // 删除用户角色关联
            await _userRoleRepository.DeleteByUserIdAsync(id);

            // 删除用户
            await _userRepository.DeleteAsync(user.Id);

            // 清除用户相关缓存
            await _cacheService.RemoveAsync($"user_permissions:{id}");
        }

        /// <summary>
        /// 分配角色
        /// </summary>
        public async Task AssignRolesAsync(AssignRolesDto input)
        {
            var user = await _userRepository.GetByIdAsync(input.UserId);
            if (user == null)
            {
                throw new ArgumentException($"用户不存在: {input.UserId}");
            }

            // 删除现有角色
            await _userRoleRepository.DeleteByUserIdAsync(input.UserId);

            // 添加新角色
            if (input.RoleIds?.Any() == true)
            {
                var userRoles = input.RoleIds.Select(roleId => UserRole.Create(input.UserId, roleId));
                await _userRoleRepository.AddRangeAsync(userRoles);
            }

            // 清除用户权限缓存
            await _cacheService.RemoveAsync($"user_permissions:{input.UserId}");
        }
        /// <summary>
        /// 根据用户ID修改密码
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="newPassword"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        public async Task UpdatePasswordAsync(Guid userId, string newPassword)
        {
            var user = await _userRepository.GetByIdAsync(userId);
            if (user == null)
            {
                throw new ArgumentException($"用户不存在: {userId}");
            }

            user.UpdatePassword(_passwordHasher.HashPassword(newPassword));
            await _userRepository.UpdateAsync(user);
        }
        


    }
} 